/**
 *  @file dfa.c
 *  @brief Animation of a deterministics finite automaton
 *  @author Prashant Hebbar
 *  @date 1990/05/18
 *  $Id: dfa.c 10 2007-06-28 20:08:57Z mfms $
 */

/*
 *  Copyright (C) 1990, 1997  Prashant Hebbar, Matthias Stallmann.
 *  Contact: matt_stallmann@ncsu.edu
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program (file COPYING.txt); if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
 *  USA.
 */

#include "Gdr.h"
#include <strings.h> /* index() -- added 8/28/97 */

 /* declarations and macros for the animation */
static TWIN pwin;               /* window for user prompts */
#define XW 1                    /* prompt window coordinates */
#define YW 1
#define init_prompt_window (pwin = create_text_window(XW,YW,""))
#define destroy_prompt_window (kill_window(pwin))
#define wait(msg) (write_text_window(pwin,msg),suspend_animation(),\
				   hide_window(pwin))
static edge e = NULL_EDGE;      /* so that highlighting can be removed */

/* transition(q,ch): returns the new state after reading symbol ch;
	q is the current state (null vertex if no transition is
	defined */
vertex transition(vertex q, char ch)
{
	e = first_out_edge(q);
	while (e != NULL_EDGE) {

		/* if ch occurs in the label of e then
			new state is vertex at the other end of e */
		if (index(edge_label(e),ch)) {
			highlight_edge(e);
			return (other_vertex(q,e));
		}
		e = next_out_edge(q,e);
	}
	return (NULL_VERTEX);
}

/* do the DFA animation: assumes that vertex 0 is start
	state, and that the label of vertex 0 contains the input string */
void animat(void)
{
	int i;
	char *stg;
	vertex q = 0, q_new;
	vertex v;

	for_all_vertices(v) {
	  hide_vertex_label(v);
	}

	/* prompt user for input string */
	init_prompt_window;
	change_vertex_label(q,"");
	expose_vertex_label(q);
	wait("Put input string in label\n of vertex 0 (the start state)\n and click Resume");

	/* read input string */
	stg = vertex_label(q);
	expose_vertex_label(q);

	/* compute new state as long as input remains (i is index of
		current character) */
	for (i = 0; stg[i] != '\0'; i++) {
	 start:	q_new = transition(q,stg[i]);
	  	if (q_new == NULL_VERTEX) {
			wait("No transition defined!\n (edit and click resume)");
			goto start;
		}
		hide_vertex_label(q);
		q = q_new;
		change_vertex_label(q,&stg[i+1]);
		expose_vertex_label(q);
		wait("Next transition?\n (click Resume)");
		un_highlight_edge(e); /* remove highlighting from
					 previous edge */
	}
	wait("End of simulation.\n (click Resume to enter edit mode)");
	hide_vertex_label(q);
	destroy_prompt_window;
} /* animat ends */

/*  [Last modified: 2007 06 28 at 19:43:53 GMT] */
